package com.gjy.concurrency.util;

import org.junit.jupiter.api.Test;

import java.util.concurrent.*;

/**
 * @author 宫静雨
 * @version 1.0
 * @since 2023-03-08 15:37:14
 */
public class CountDownLatch2Test {

    @Test
    public void test4() {
        Exchanger<String> exchanger = new Exchanger<>();

        new Thread(() -> {
            try {
                String hello = exchanger.exchange("Hello");
                System.out.println("hello = " + hello);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }).start();

        new Thread(() -> {
            try {
                String hello = exchanger.exchange("World");
                System.out.println("World = " + hello);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }).start();

        new Thread(() -> {
            try {
                String hello = exchanger.exchange("Worldcc");
                System.out.println("Worldcc = " + hello);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }).start();

        new Thread(() -> {
            try {
                String hello = exchanger.exchange("Worlddd");
                System.out.println("Worlddd = " + hello);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }).start();
    }

    @Test
    public void test3() throws InterruptedException {
        int a = 10;
        Semaphore semaphore = new Semaphore(a);
        ExecutorService pool = Executors.newFixedThreadPool(3);
        for (int i = 0; i < a; i++) {
            pool.execute(() -> {
                System.out.println("Thread.currentThread().getName() = " + Thread.currentThread().getName());
                semaphore.release();
            });
        }
        semaphore.acquire();

        System.out.println("Thread.currentThread().getName() = " + Thread.currentThread().getName());
    }

    @Test
    public void test2() {
        int a = 10;
        CyclicBarrier cyclicBarrier = new CyclicBarrier(a, () -> System.out.println(Thread.currentThread().getName()));
        ExecutorService pool = Executors.newFixedThreadPool(a);

        for (int i = 0; i < a; i++) {
            pool.execute(() -> {
                try {
                    System.out.println("Thread.currentThread().getName() 1= " + Thread.currentThread().getName());
                    cyclicBarrier.await();
                    System.out.println("Thread.currentThread().getName() 2= " + Thread.currentThread().getName());
                } catch (Exception e) {
                    throw new RuntimeException(e);
                }
            });
        }
        System.out.println("HELLO");
    }

    @Test
    public void test1() throws InterruptedException {
        int a = 10;
        CountDownLatch cdl = new CountDownLatch(a);
        ExecutorService pool = Executors.newFixedThreadPool(3);
        for (int i = 0; i < a; i++) {
            pool.execute(() -> {
                System.out.println("Thread.currentThread().getName() = " + Thread.currentThread().getName());
                cdl.countDown();
                cdl.countDown();
            });
        }
        cdl.await();
        System.out.println("HELLO WORLD");
    }
}
